﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MonitoringProgressWithEvents
{
  class Program
  {

    // This script burns data files to disc in a single session 
    // using files from a single directory tree. 
    // Copyright (C) Microsoft Corp. 2006

    // *** CD/DVD disc file system types
    public const int FsiFileSystemISO9660 = 1;
    public const int FsiFileSystemJoliet = 2;
    public const int FsiFileSystemUDF102 = 4;

    static void Main(string[] args)
    {

      // The contents of the Main method were copied directly from BurnADiscImage project
      // Only added the line to subscribe to the update event

      dynamic Index;              // Index to recording drive.
      dynamic recorder;            // Recorder object
      dynamic Path;             // Directory of files to burn
      dynamic Stream;              // Data stream for burning device

      Index = 1;            // Second drive on the system
      Path = @"g:\BurnDir";     // Files to transfer to disc

      // Create a DiscMaster2 object to connect to optical drives.
      dynamic g_DiscMaster;
      g_DiscMaster = new IMAPI2.MsftDiscMaster2();

      // Create a DiscRecorder object for the specified burning device.
      dynamic uniqueId;
      recorder = new IMAPI2.MsftDiscRecorder2();
      uniqueId = g_DiscMaster.Item(Index);
      recorder.InitializeDiscRecorder(uniqueId);

      // Create an image stream for a specified directory.
      dynamic FSI;                 // Disc file system
      dynamic Dir;                 // Root directory of the disc file system
      dynamic dataWriter;

      // Create a new file system image and retrieve root directory
      FSI = new IMAPI2FS.MsftFileSystemImage();
      Dir = FSI.Root;

      //Create the new disc format and set the recorder
      dataWriter = new IMAPI2.MsftDiscFormat2Data();
      dataWriter.Recorder = recorder;
      dataWriter.ClientName = "IMAPIv2 TEST";

      FSI.ChooseImageDefaults(recorder);

      // This is the only line added to this code vs. the BurningADiscImage project
      dataWriter.Update += new IMAPI2.DDiscFormat2DataEvents_UpdateEventHandler(dataWriter_Update);

      // Add the directory and its contents to the file system 
      Dir.AddTree(Path, false);

      // Create an image from the file system
      dynamic result;
      result = FSI.CreateResultImage();
      Stream = result.ImageStream;

      // Write stream to disc using the specified recorder.
      Console.WriteLine("Writing content to disc...");
      dataWriter.Write(Stream);

      Console.WriteLine("----- Finished writing content -----");

    }

    static void dataWriter_Update(dynamic @object, dynamic progress)
    {
      try
      {
        string strTimeStatus;
        strTimeStatus = "Time: " + progress.ElapsedTime + " / " + progress.TotalTime;
        int currentAction = progress.CurrentAction;


        switch (currentAction)
        {
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_CALIBRATING_POWER:
            Console.WriteLine("Calibrating Power (OPC) " + strTimeStatus);
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_COMPLETED:
            Console.WriteLine("Completed the burn.");
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_FINALIZATION:
            Console.WriteLine("Finishing the writing " + strTimeStatus);
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_FORMATTING_MEDIA:
            Console.WriteLine("Formatting media " + strTimeStatus);
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_INITIALIZING_HARDWARE:
            Console.WriteLine("Initializing Hardware " + strTimeStatus);
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_VALIDATING_MEDIA:
            Console.WriteLine("Validating media " + strTimeStatus);
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_VERIFYING:
            Console.WriteLine("Verifying the data.");
            break;
          case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_WRITING_DATA:
            dynamic totalSectors;
            dynamic writtenSectors;
            dynamic startLba;
            dynamic lastWrittenLba;
            dynamic percentDone;
            totalSectors = progress.SectorCount;
            startLba = progress.StartLba;
            lastWrittenLba = progress.LastWrittenLba;
            writtenSectors = lastWrittenLba - startLba;
            percentDone = FormatPercent(Convert.ToDecimal(writtenSectors) / Convert.ToDecimal(totalSectors));
            Console.WriteLine("Progress:  " + percentDone + "  " + strTimeStatus);
            break;
          default:
            Console.WriteLine("Unknown action: " + progress.CurrentAction.ToString());
            break;
        }



      }
      catch (Exception ex)
      {
        Console.WriteLine("Error: " + ex.Message);
      }
    }

    private static dynamic FormatPercent(dynamic d)
    {
      return d.ToString("0%");
    }

  }
}
